/*--------------------------------------------------------------------------------------------------
Yatak Operation System Project Copyright 2012-2013
Author : Ilya Churaev
Started : 8 Jan 2013		Updated : 12 Jan 2013
File Name : cpuid.h			Purpose : detect installed processor.
--------------------------------------------------------------------------------------------------*/
#ifndef _CPUID_H
#define _CPUID_H

#ifdef __cplusplus
extern "C" {
#endif

#ifndef _TYPES_H
#include <types.h>
#endif

#define PACKED __attribute__((packed))

struct cpuinfo_x86
{
	unsigned char	x86 /*PACKED*/;		/* CPU family */
	unsigned char	x86_vendor /*PACKED*/;	/* CPU vendor */
	unsigned char	x86_model /*PACKED*/;
	unsigned char	x86_mask /*PACKED*/;
	char	wp_works_ok  /*PACKED*/;	/* It doesn't on 386's */
	char	hlt_works_ok  /*PACKED*/;	/* Problems on some 486Dx4's and old 386's */
	char	hard_math  /*PACKED*/;
	char	rfu  /*PACKED*/;
	int	cpuid_level  PACKED;	/* Maximum supported CPUID level, -1=no CPUID */
	unsigned int	x86_capability  PACKED;
	char	x86_vendor_id[16]  /*PACKED*/;
	char	x86_model_id[64]  /*PACKED*/;
	int 	x86_cache_size  PACKED;  /* in KB - valid for CPUS which support this
				    call  */
	int	fdiv_bug  PACKED;
	int	f00f_bug  PACKED;
	unsigned long loops_per_sec  PACKED;
	unsigned long *pgd_quick  PACKED;
	unsigned long *pte_quick  PACKED;
	unsigned long pgtable_cache_sz  PACKED;
};

struct cpu_info
{
	unsigned int vendor_id;
	size_t stepping;
	size_t model;
	char model_str [256];
	char brand [256];
	size_t family;
	char family_str [256];
	size_t type;
	char type_str [64];
	size_t reserved;
};

int detect_cpu(struct cpu_info *cpu);

#define cpuid(in, a, b, c, d) __asm__("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in));

#ifdef __cplusplus
}
#endif

#endif
